package org.osgiutils.common.tiger;

import java.lang.reflect.Array;
import java.util.LinkedList;
import java.util.List;

import net.jcip.annotations.GuardedBy;
import net.jcip.annotations.ThreadSafe;

import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.util.tracker.ServiceTracker;
import org.osgi.util.tracker.ServiceTrackerCustomizer;

@ThreadSafe
public class NAryTracker<S> extends ServiceTracker {
	
	@GuardedBy("services")
	private final List<S> services = new LinkedList<S>();
	private final Class<S> serviceClass;
	
	protected NAryTracker(BundleContext context, Class<S> serviceClass,
			ServiceTrackerCustomizer customizer) {
		super(context, serviceClass.getName(), customizer);
		this.serviceClass = serviceClass;
	}

	@SuppressWarnings("unchecked")
	@Override
	public final Object addingService(ServiceReference reference) {
		S service = (S) context.getService(reference);
		synchronized (services) {
			services.add(service);
		}
		return service;
	}

	@Override
	public final void removedService(ServiceReference reference, Object service) {
		synchronized (services) {
			services.remove(service);
		}
		context.ungetService(reference);
	}
	
	@SuppressWarnings("unchecked")
	protected final S[] getSnapshot() {
		S[] result;
		synchronized (services) {
			result = services.toArray((S[]) Array.newInstance(serviceClass, services.size()));
		}
		return result;
	}

}
